package com.example.blue_classic_plus.ble;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@SuppressLint("NewApi")
public class BleClient {

    private final String ClientStateType = "clientState";
    private final String ServerMsgType = "serverMsg";


    private String uuid;
    private String name;

    Handler handler;

    BluetoothManager bluetoothManager;
    BluetoothAdapter bluetoothAdapter;
    private BluetoothGatt bluetoothGatt;

    public boolean isConnecting;

    private boolean scaning;

    public BleClient(Context context, String uuid, String name, Handler handler) {
        this.uuid = uuid;
        this.name = name;
        this.handler = handler;

        bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();
    }

    ///连接服务器回调
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        // 连接状态改变的处理
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) {
                System.out.println("BleClient 连接gatt服务器成功");
                gatt.discoverServices();
            } else {
                isConnecting = false;
                bluetoothGatt.close();
                System.out.println("BleClient 连接gatt服务器失败");
                toFlutterType(ClientStateType, 10, "连接失败");
            }
        }


        @Override
        public void onServiceChanged(@NonNull BluetoothGatt gatt) {
            super.onServiceChanged(gatt);
            System.out.println("BleClient 蓝牙服务端关闭了");
            toFlutterType(ClientStateType, 10, "连接失败");
            stopConnect();
        }

        // 服务发现的处理
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
//                List<BluetoothGattService> services = gatt.getServices();
//                for (BluetoothGattService service : services) {
//                    UUID serviceUuid = service.getUuid();
//                    // 在这里处理每个服务
//                    System.out.println("发现的服务uuid = " + serviceUuid);
//                }

                ///只关心指定的服务
                BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(uuid));
                System.out.println("指定的服务对象 " + service);
                if (service != null) {
                    BluetoothGattCharacteristic notifyCharacteristic = service.getCharacteristic(UUID.fromString(uuid));
                    if (notifyCharacteristic != null) {
                        // 订阅通知
                        boolean isNotificationEnabled = bluetoothGatt.setCharacteristicNotification(notifyCharacteristic, true);
                        System.out.println("BleClient isNotificationEnabled = " + isNotificationEnabled);
                        if (isNotificationEnabled) {
                            // 这个UUID固定写死的，由蓝牙的规范定义的
                            BluetoothGattDescriptor descriptor = notifyCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                            if (descriptor != null) {
                                // 写入描述符
                                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                boolean writeDescriptor = bluetoothGatt.writeDescriptor(descriptor);
                                if (writeDescriptor) {
                                    System.out.println("BleClient 订阅特征通知成功,这是才算真正的成功");
                                    toFlutterType(ClientStateType, 8, "客户端连接成功");
                                    return;
                                }
                            }
                        }
                    }
                }
                System.out.println("BleClient 订阅特征通知失败，也是算失败");
                toFlutterType(ClientStateType, 10, "连接失败");
                stopConnect();
            } else {
                System.out.println("BleClient onServicesDiscovered received: " + status);
                toFlutterType(ClientStateType, 10, "连接失败");
            }
        }

        ///可以不要
        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
//            if (status == BluetoothGatt.GATT_SUCCESS) {
//                //开启监听成功，可以向设备写入命令了
//                System.out.println("BleClient 开启监听成功");
//            } else {
//                System.out.println("BleClient 开启监听失败 status" + status);
//            }
        }

        // 特性读取的处理
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            System.out.println("BleClient onCharacteristicRead");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                System.out.println("BleClient Read characteristic: " + characteristic.getUuid().toString() + " Value: " + characteristic.getValue().toString());
            }
        }

        // 特性写入的处理
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            System.out.println("BleClient onCharacteristicWrite");
        }

        // 收到特性消息的处理
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            byte[] data = characteristic.getValue();
            // 这里的data就是接收到的数据
            //System.out.println("BleClient 收到了消息: " + new String(data));
            toFlutterType(ServerMsgType, 1, new String(data));
        }
    };

    // 扫描结果Callback
    private final ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            BluetoothDevice dev = result.getDevice();
            //ScanRecord scanRecord = result.getScanRecord();
            System.out.println("BleScanner " + "Device found: " + dev.getName() + " (" + dev.getAddress() + ")");
            if (name.equals(dev.getName()) && scaning) {
                scaning = false;
                stopScan();
                connect(dev);
            }
        }
    };

    /// 连接设备
    public void connect(BluetoothDevice bluetoothDevice) {
        if (bluetoothAdapter == null) {
            System.out.println("BleClient connect方法执行失败");
            toFlutterType(ClientStateType, 2, "不支持使用蓝牙");
            return;
        }
        bluetoothGatt = bluetoothDevice.connectGatt(null, false, mGattCallback);
    }


    ///开始扫描设备
    public void startScan() {
        isConnecting = true;
        final BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        scaning = true;
        bluetoothLeScanner.startScan(mScanCallback);
    }

    ///结束扫描
    public void stopScan() {
        final BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        bluetoothLeScanner.stopScan(mScanCallback);
    }

    ///结束连接
    public void stopConnect() {
        if (bluetoothGatt == null) return;

        isConnecting = false;
        bluetoothGatt.disconnect();
        bluetoothGatt.close();
    }


    ///发送消息给Flutter
    public void toFlutterType(String type, int code, String msg) {
        Map<String, Object> map = new HashMap<>();
        map.put("type", type);
        map.put("code", code);
        if (!TextUtils.isEmpty(msg)) {
            map.put("msg", msg);
        }
        Message message = this.handler.obtainMessage(0, map);
        this.handler.sendMessage(message);
    }

}
